﻿namespace Pibby.Core.IO
{
	using System;

	/// <summary>
	/// Detects removable drives connecting and disconnecting from the system.
	/// </summary>
	public abstract class RemovableDriveDetector
	{
		#region Events

		public event EventHandler<RemovableDriveEventArgs> RemovableDriveArrived;

		public event EventHandler<RemovableDriveEventArgs> RemovableDriveRemoved;

		#endregion

		#region Event Signalling

		protected virtual void SignalDeviceArrival(int driveId)
		{
			this.SignalMediaArrival(this.CreateEventArgs(driveId, RemovableDriveStatus.Connected));
		}

		protected virtual void SignalMediaArrival(RemovableDriveEventArgs e)
		{
			EventHandler<RemovableDriveEventArgs> arrived = this.RemovableDriveArrived;

			if (arrived != null)
			{
				arrived(this, e);
			}
		}

		protected virtual void SignalDeviceRemoval(int driveId)
		{
			this.SignalMediaRemoval(this.CreateEventArgs(driveId, RemovableDriveStatus.Disconnected));
		}

		protected virtual void SignalMediaRemoval(RemovableDriveEventArgs e)
		{
			EventHandler<RemovableDriveEventArgs> removed = this.RemovableDriveRemoved;

			if (removed != null)
			{
				removed(this, e);
			}
		}

		protected virtual RemovableDriveEventArgs CreateEventArgs(int driveId, RemovableDriveStatus status)
		{
			string driveName = string.Format(System.Globalization.CultureInfo.InvariantCulture, 
												"{0}:\\", DriveMaskTranslator.IdentifyDriveLetter((uint)driveId));

			string volumeName = string.Empty;

			IDrive di = DriveFinder.FindDrive(driveName);

			if (di != null && di.IsReady)
			{
				volumeName = di.VolumeLabel;
			}

			return new RemovableDriveEventArgs(driveName, volumeName, status);
		}

		#endregion
	}
}
